Skip to content

Handle nullable drag entries in desktop_drop web to avoid zip-drag crashes - #459

Draft
boyan01 with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-dragging-file-crash
Draft

Handle nullable drag entries in desktop_drop web to avoid zip-drag crashes#459
boyan01 with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-dragging-file-crash

Conversation

Copilot AI commented Jan 14, 2026

Copy link
Copy Markdown
Contributor

Dragging files from zip archives on web could crash when DataTransferItem.webkitGetAsEntry() returned null.

  • Null-safe drop handling

    • Guard against null entries and skip missing items.
    • Fallback to building drop items from getAsFile() when entry metadata is unavailable.
    • Avoid invoking performOperation_web when no items are produced.
  • Shared file mapping

    • Added _fileToWebDropItem helper to unify file-to-drop-item conversion for both entry and fallback paths.

Example:

final item = items[index];
final entry = item.webkitGetAsEntry();
if (entry != null) {
  return _entryToWebDropItem(entry);
}
final file = item.getAsFile();
if (file != null) {
  return _fileToWebDropItem(file, relativePath: null);
}
return Future.value(null);
Original prompt

This section details on the original issue you should resolve

<issue_title>[desktop_drop_web] Dragging file from zip file crashes</issue_title>
<issue_description>## Reproduce Steps

  1. Drag a file from a zip file (windows explorer)
  2. Observer error when releasing.

Expected behavior

No errors

Version (please complete the following information):

  • Flutter Version: master
  • OS: Windows + Chrome
  • plugin: [e.g. desktop_drop: 0.7.0]

Stack trace:

errors.dart:274 Uncaught DartError: Unexpected null value.
    at Object.throw_ [as throw] (errors.dart:274:3)
    at Object.nullCheck (operations.dart:950:18)
    at desktop_drop_web.dart:92:46
    at List.generate (core_patch.dart:377:46)
    at desktop_drop_web.dart:90:24
    at Object._callDartFunctionFast1 (js_allow_interop_patch.dart:224:27)
    at ret (js_allow_interop_patch.dart:84:15)
```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits January 14, 2026 03:06
Co-authored-by: boyan01 <17426470+boyan01@users.noreply.github.com>
Co-authored-by: boyan01 <17426470+boyan01@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix crash when dragging file from zip on desktop drop Handle nullable drag entries in desktop_drop web to avoid zip-drag crashes Jan 14, 2026
Copilot AI requested a review from boyan01 January 14, 2026 03:10
jamesaorson added a commit to autobutler-org/quark that referenced this pull request Sep 11, 2026
Refs #1831

## What

Drag-and-drop upload was broken on web: the drop area highlighted,
releasing never uploaded, and the highlight stayed stuck until a page
refresh. The reporter hit it dragging from the browser's downloads menu.

`desktop_drop`'s web handler calls `webkitGetAsEntry()!` on every item
in the drag. That returns null for `kind == 'string'` items, and a drag
routinely carries them alongside its files — the downloads menu sends
`text/uri-list` and `text/plain` next to the file. The null assert
throws synchronously inside `List.generate`, before the `.catchError`
further down the chain is attached, so `performOperation_web` is never
invoked. No `DropDoneEvent` reaches the app, the file never uploads, and
`DropTarget`'s status never resets — hence the stuck highlight. The file
was in the drag the whole time.

This points `desktop_drop` at our fork, which null-guards the entry and
falls back to `getAsFile()`. `getAsFile()` and `webkitGetAsEntry()` are
not equivalent — the latter needs a filesystem-backed entry and returns
null for exactly the items the former handles. That is also why the same
drag works on other web upload targets and not on ours.

## Changes

- `pubspec.yaml`: `dependency_overrides` pointing `desktop_drop` at
`autobutler-org/flutter-plugins` `main`, with a comment explaining why
and when to remove it
- `pubspec.lock`: resolved to `29e5924`

Fork commit:
[autobutler-org/flutter-plugins@29e5924](autobutler-org/flutter-plugins@29e5924)

Upstream PR:
[MixinNetwork/flutter-plugins#503](MixinNetwork/flutter-plugins#503).
The root cause is already filed upstream as
[#456](MixinNetwork/flutter-plugins#456) from
a different trigger (dragging out of a zip viewer, likewise no
`FileSystemEntry`); the downloads-menu case is new evidence on the same
defect. A stalled draft,
[#459](MixinNetwork/flutter-plugins#459), fixes
the null assert the same way — our version additionally notifies with
the resulting list even when it is empty, so a drag carrying no files at
all (a dragged link, selected text) clears the drop target instead of
wedging it the same way.

## PR Type

- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs / content
- [ ] Chore / tooling
- [ ] Tests

## Surface

- [ ] Backend (Go)
- [x] Frontend (Flutter)
- [ ] API / swagger
- [ ] CI / workflows
- [ ] Docs / content only

## Testing

- [x] Local testing recommended (UI changes, routing, behavior changes)
- [ ] Local testing not needed (logic-only, docs, trivial change)
- [ ] Includes new automated tests
- [x] Manually tested by author

Tested side by side on macOS: stock 0.8.4 on one port reproduces the
failure, the patched build on another uploads normally. The served
bundles were checked to confirm the difference was really the patch —
`getAsFile` appears in the compiled output of the patched build and is
absent from stock 0.8.4. `make check` passes.

## Bot Review Guidance

The risk here is the dependency override, not application code. Worth
checking that tracking a fork's `main` is acceptable, and that
`pubspec.lock` pinning the resolved commit is considered sufficient for
reproducibility.

## Notes

**Deliberately `Refs`, not `Closes`.** This fixes the crash but not the
whole issue. Three independent defects found during the investigation
are untouched and #1831 should stay open for them:

- 90 ms folder-hover debounce race (`file_browser_page.dart:763-787`,
`:2199`) — a drop released between the page target and a folder target
lands in neither; separately, after hovering any folder row the
page-level highlight is dead for the rest of that drag
- `FolderDropTarget` has no `enable` gate (`folder_drop_target.dart:35`)
while the page target gates on `!_isUploading` (`:2171`), so folder rows
highlight during a background upload and then early-return
- `_isWebDragging` has no reset path other than an exit/done event — no
timeout, no reset on rebuild

**No automated coverage.** There are no widget tests for
`FolderDropTarget`, `FolderDropWrapper`, or the page's drag state
machine; the only existing test is pure-function coverage of
`flattenDroppedItems`. Every defect above lives in the untested wiring.

**Cleanup owed.** The override tracks a moving ref. `pubspec.lock` pins
the resolved commit so builds stay reproducible, but `pub upgrade` will
follow wherever that branch goes. Remove the override once a
`desktop_drop` release carrying the fix reaches pub.dev — the comment in
`pubspec.yaml` is the only thing carrying that reminder.

Signed-off-by: James Orson <jamesaorson@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[desktop_drop_web] Dragging file from zip file crashes

2 participants